Skip to content

chore(deps): update marked to v18 - #603

Merged
farnabaz merged 1 commit into
vercel:mainfrom
sleitor:chore/marked-v18
Aug 31, 2026
Merged

chore(deps): update marked to v18#603
farnabaz merged 1 commit into
vercel:mainfrom
sleitor:chore/marked-v18

Conversation

@sleitor

@sleitor sleitor commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Closes #566

Bumps marked from ^17.0.1 to ^18.0.11 (latest) in packages/streamdown/package.json.

Breaking change in marked v18

marked v18 no longer absorbs a block token's trailing blank line(s) into its own raw. That whitespace now surfaces as a separate space token immediately following the block (observed on html, heading, and table block tokens).

Example, for <ai-thinking>\n\n**bold**\n\n</ai-thinking>\n\n# Outside:

  • v17: html('<ai-thinking>\n\n'), paragraph('**bold**'), space('\n\n'), html('</ai-thinking>\n\n'), heading('# Outside')
  • v18: html('<ai-thinking>'), space('\n\n'), paragraph('**bold**'), space('\n\n'), html('</ai-thinking>'), space('\n\n'), heading('# Outside')

The token.raw lossless concatenation invariant still holds (joining all raw values still reconstructs the source exactly) — the difference is purely in how the whitespace is bucketed into tokens.

Fix

parseMarkdownIntoBlocks (packages/streamdown/lib/parse-blocks.tsx) tracks an htmlStack to merge tokens between a custom tag's opening and closing HTML block tokens into one block. Under v17, the closing tag's trailing blank line was absorbed into that same html token, so it was included in the merge before the stack was popped. Under v18, that blank line is a separate space token emitted after the closing tag pops the stack, so it fell through and got pushed as its own standalone block — turning what should be 2 blocks into 3.

Since a bare space token is never meaningful content on its own, the fix folds any space token into the previous block (when one exists) instead of pushing it as a new block:

if (token.type === "space" && mergedBlocksLen > 0) {
  mergedBlocks[mergedBlocksLen - 1] += currentBlock;
  continue;
}

This restores block boundaries/counts identical to v17 output, for both the htmlStack-merge path and the general case. The existing math-block merge logic ($$ odd-count tracking) and previousTokenWasCode tracking are untouched and placed after this check.

A regression test was added in __tests__/custom-tag-markdown.test.tsx asserting the v18 tokenization shape doesn't create an extra block and that blocks.join("") === input (lossless invariant).

TypeScript

marked v18's internal TS toolchain bumped to v6, but this is not a consumer-facing constraint — TypeScript 5.9.3 (what this repo pins) typechecks cleanly against marked@18's .d.ts with skipLibCheck: false. No TS upgrade needed.

Tests

pnpm test in packages/streamdown: all 1145 tests pass (1144 pre-existing + 1 new regression test), 84 test files.

Changeset

Added .changeset/update-marked-v18.md as a patch for the streamdown package (dependency bump + internal parser fix, no public API change).

Bump marked from ^17.0.1 to ^18.0.11.

marked v18 no longer folds a block token's trailing blank line(s) into
its own raw; that whitespace now surfaces as a separate space token
immediately after the block (html/heading/table, etc.). This broke
parseMarkdownIntoBlocks, which relied on trailing blank lines being
absorbed into html blocks: a dangling space token after a closed
custom-tag HTML block was emitted as its own standalone block instead
of being merged.

Fix parseMarkdownIntoBlocks to fold a space token into the previous
block instead of pushing it as a new block, restoring v17-identical
block boundaries/counts. The lossless token.raw concatenation
invariant is preserved. Added a regression test for the v18 tokenization
shape.

TypeScript 5.9.3 typechecks cleanly against marked@18's .d.ts despite
marked's internal TS bump to v6, so no TS upgrade is required.

All 1145 tests pass.

Closes vercel#566
@vercel

vercel Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

@sleitor is attempting to deploy a commit to the Vercel Team on Vercel.

A member of the Team first needs to authorize it.

@farnabaz farnabaz left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks 👍

@farnabaz
farnabaz merged commit a155a9e into vercel:main Aug 31, 2026
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update marked to v18

2 participants